package com.sf.shiva.oms.common.util;

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.sf.shiva.oms.common.constant.MapCompareEnum;

/**
 * 
 * 描述：集合工具类
 * 
 * <pre>
 * HISTORY
 * ****************************************************************************
 *  ID   DATE            PERSON            REASON
 *  1    2016年9月13日        866321            Create
 * ****************************************************************************
 * </pre>
 * 
 * @author 866321
 */
public final class CollectionUtil {
    /**
     * 私有构造方法
     */
    private CollectionUtil() {}

    /**
     * 判断是否为空
     * 
     * @param collection
     *            集合
     * @return 是否为空
     */
    public static boolean isEmpty(Collection<?> collection) {
        if (null == collection || collection.isEmpty()) {
            return true;
        }
        return false;
    }

    /**
     * 判断是否不为空
     * 
     * @param collection
     *            集合
     * @return 是否不为空
     */
    public static boolean isNotEmpty(Collection<?> collection) {
        return !isEmpty(collection);
    }

    /**
     * 获取列表中最后一个数据
     * 
     * @param <E>
     *            类
     * @param list
     *            列表
     * @return 最后一个数据
     */
    public static <E> E getLastData(List<E> list) {
        if (CollectionUtil.isEmpty(list)) {
            throw new IllegalArgumentException("List cannot be null.");
        }
        return list.get(list.size() - 1);
    }

    /**
     * 将源集合合并到目标集合中，并去重
     * 
     * @param dest
     *            源集合
     * @param source
     *            目标集合
     * @author 866321-2016年12月22日
     */
    public static <E> void union(Collection<E> dest, Collection<E> source) {
        if (CollectionUtil.isNotEmpty(source)) {
            for (E data : source) {
                if (!dest.contains(data)) {
                    dest.add(data);
                }
            }
        }
    }
    
    /**
     * list添加对象(添加e不为空的对象)
     * @param list  
     * @param e
     * @author 80002031-2017年9月20日
     */
    public static <E> void listAdd(List<E> list , E e){
        if (null != e){
            list.add(e);
        }
    }

    /**
     * 对新老数据进行判断处理(用key值进行判断)
     * MapCompareEnum 为REMOVE,MODIFY,ADD
     * 当newMap为空时,直接返回MapCompareEnum = remove,List 为oldMapkey的值
     * 当newMap不为空时,与oldMap进行判断</br>
     * 添加存在newMap而不存在oldMap中的数据,List为newMap中的对象</br>
     * 删除不存在newMap而存在oldMap中的数据,List为oldMap中的对象</br>
     * 修改存在newMap和oldMap中的数据,List为oldMap中的对象</br>
     * @param newMap
     * @param oldMap
     * @author 80002031-2017年9月21日
     */
    public static <E>Map<MapCompareEnum,List<E>> compareMap(Map<String,E> newMap,Map<String,E> oldMap){
        Map<MapCompareEnum, List<E>> operateMap = new HashMap<>();
        if ((null ==newMap || newMap.isEmpty()) && (null == oldMap || oldMap.isEmpty())){
            return Collections.emptyMap();
        }
        if (null == newMap || newMap.isEmpty() ){
            operateRemoveMap(oldMap, operateMap);
        }else{
            operateNewMap(newMap, oldMap, operateMap);
            operateOldMap(newMap, oldMap, operateMap);
        }
        return operateMap;
    }

    /**
     * 删除数据处理
     * @param oldMap
     * @param operateMap
     * @author 80002031-2017年9月22日
     */
    private static <E> void operateRemoveMap(Map<String, E> oldMap,
            Map<MapCompareEnum, List<E>> operateMap) {
        Collection<E> collection = oldMap.values();
        operateMap.put(MapCompareEnum.REMOVE, new ArrayList<>(collection));
    }

    /**
     * 新数据填充处理
     * @param newMap
     * @param oldMap
     * @param operateMap
     * @author 80002031-2017年9月22日
     */
    private static <E> void operateNewMap(Map<String, E> newMap,
            Map<String, E> oldMap, Map<MapCompareEnum, List<E>> operateMap) {
        for (Map.Entry<String, E> entry : newMap.entrySet()){
            if (oldMap.containsKey(entry.getKey())){//新老都存在则进行修改
                fillMap(MapCompareEnum.MODIFY, operateMap, oldMap.get(entry.getKey()));
            }else{  //新存在老不存在则进行新增
                fillMap(MapCompareEnum.ADD, operateMap, entry.getValue());
            }
        }
    }

    /**
     * 老数据填充处理
     * @param newMap
     * @param oldMap
     * @param operateMap
     * @author 80002031-2017年9月22日
     */
    private static <E> void operateOldMap(Map<String, E> newMap,
            Map<String, E> oldMap, Map<MapCompareEnum, List<E>> operateMap) {
        if (null != oldMap && !oldMap.isEmpty()){
            for (Map.Entry<String, E> entry : oldMap.entrySet()){
                if (!newMap.containsKey(entry.getKey())){
                    fillMap(MapCompareEnum.REMOVE, operateMap, entry.getValue());
                }
            }
        }
    }
    
    /**
     * map数据填充
     * @param type
     * @param map
     * @param e
     * @author 80002031-2017年9月21日
     */
    private static <E>void fillMap(MapCompareEnum type,Map<MapCompareEnum,List<E>> map,E e){
        List<E> list ;
        if (map.containsKey(type)){
            list = map.get(type);
        }else{
            list = new ArrayList<>();
        }
        list.add(e);
        map.put(type, list);
    }
    
    
    /**
     * list转换为map
     * @param list
     * @param keyMethodName
     * @param c
     * @return
     * @author 80002031-2018年2月9日
     */
    public static <K, V> Map<K, V> list2Map(List<V> list, String keyMethodName,Class<V> c ) {  
        Map<K, V> map = new HashMap<>();  
        if (list != null) {  
            try {  
                Method methodGetKey = c.getMethod(keyMethodName);  
                for (int i = 0; i < list.size(); i++) {  
                    V value = list.get(i);  
                    @SuppressWarnings("unchecked")  
                    K key = (K) methodGetKey.invoke(list.get(i));  
                    map.put(key, value);  
                }  
            } catch (Exception e) {  
                throw new IllegalArgumentException("field can't match the key!");  
            }  
        }  
        return map;  
    } 
    
    
    /**
     * list转换为map
     * @param list
     * @param keyMethodName
     * @param c
     * @return
     * @author 80002031-2018年2月9日
     */
    public static <K, V> Map<K, List<V>> list2MapList(List<V> list, String keyMethodName,Class<V> c ) {  
        Map<K, List<V>> map = new HashMap<>();  
        if (list != null) {  
            try {  
                Method methodGetKey = c.getMethod(keyMethodName);  
                for (int i = 0; i < list.size(); i++) {  
                    V value = list.get(i);  
                    @SuppressWarnings("unchecked")  
                    K key = (K) methodGetKey.invoke(list.get(i)); 
                    map.computeIfAbsent(key, newKey -> new ArrayList<>()).add(value);
                }  
            } catch (Exception e) {  
                throw new IllegalArgumentException("field can't match the key!");  
            }  
        }  
        return map;  
    } 

    /**
     * 深拷贝列表
     * 
     * @param source
     * @param dest
     * @author LA.01367604-2018年4月5日
     */
    public static void cloneList(List<String> source, List<String> dest) {
        dest.clear();
        for (String elem : source) {
            dest.add(elem);
        }
    }

    public static void cloneMap(Map<String, Integer> source, Map<String, Integer> dest) {
        dest.clear();
        for (Map.Entry<String, Integer> entry : source.entrySet()) {
            dest.put(entry.getKey(), entry.getValue());
        }
    }
}
